package myReflect

import (
	"fmt"
	"reflect"
)

func reflectDemo01() {
	var age interface{} = 25

	fmt.Printf("原始接口变量的类型为 %T，值为 %v \n", age, age)

	t := reflect.TypeOf(age)
	v := reflect.ValueOf(age)

	// 从接口变量到反射对象
	fmt.Printf("从接口变量到反射对象：Type对象的类型为 %T \n", t)
	fmt.Printf("从接口变量到反射对象：Value对象的类型为 %T \n", v)

	i := v.Interface()
	fmt.Println("reflect object -> interface value:", i)
}

/**
 * 反射可见性
 */
func reflectCanSet() {
	var name string = "Go编程学习"
	v := reflect.ValueOf(name)
	fmt.Println("可写性为:", v.CanSet())
}

/**
* 反射可修改
要让反射对象具备可写性，需要注意两点
   创建反射对象时传入变量的指针
   使用 Elem()函数返回指针指向的数据
*/
func reflectCanUpdate() {
	var name string = "Go编程学习"
	v := reflect.ValueOf(&name)
	fmt.Println("可写性为:", v.CanSet())

	v2 := v.Elem()
	fmt.Println("v2 可写性：", v2.CanSet())
	v2.SetString("java编程转go")
	fmt.Println(name)
}

type Profile struct {
	name   string
	age    int
	gender string
}

// hello
func (p Profile) SayHello() {
	fmt.Println("profile hello")
}

func (p Profile) sayGo() {
	fmt.Println("profile go")
}

// 自我介绍
func (p Profile) SelfIntroduce(name string, age int) {
	fmt.Printf("my name is %s, age is %d", name, age)
}

/**
 * 反射修改切片
 */
func appendToSlice(arrPtr interface{}) {
	valuePtr := reflect.ValueOf(arrPtr)
	value := valuePtr.Elem()

	value.Set(reflect.Append(value, reflect.ValueOf(3)))

	fmt.Println(value)
	fmt.Println(value.Len())
}
